#include "cmd.h"

int execute_external_cmd(command *cmd)
{
	pid_t pid;
	string *aux;
	char **argv;
	ll_iterator *it;

	pid = fork();

	if(pid < (pid_t)0) return FAILURE;

	else if(pid == (pid_t)0) /* Filho */
	{
		argv = args_to_argv(cmd);

		if(cmd->type == LOCAL)
			execve(argv[0], argv, environ);

		else
		{
			it = ll_get_iterator(path);
			while(!ll_is_end(it))
			{
				aux = (string *) ll_get(it);
				str_catc(aux, '/');
				str_cats(aux, argv[0]);
				execve(str_to_array(aux), argv, environ);

				str_delete(aux);
				ll_next(it);
			}
			free(it);
		}

		exit(NOT_FOUND);
	}

	else /* Pai */
	{
		process_insert(pid, cmd->ground);

		if(cmd->ground == FG) 		/* Foreground */
		{
		    return wait_child(pid);
		}
		else 						/* Background */
		{
			return SUCCESS;
		}
	}

	return FAILURE;
}

int wait_child(pid_t pid)
{
    int status = 0;

    while(waitpid(pid, &status, WUNTRACED) == -1 && errno == EINTR);

    if(WIFEXITED(status) && !WIFSTOPPED(status))
    {
    	process_remove(pid);

    	if(WEXITSTATUS(status) == NOT_FOUND)
            return NOT_FOUND;
        else if(WEXITSTATUS(status) == EXIT_SUCCESS)
            return SUCCESS;
        else
            return FAILURE;
    }
    else if (WIFSIGNALED(status))
    {
    	/* Terminado por signal, SIGINT por exemplo */
    	process_remove(pid);
    }
    return FAILURE;
}
